package com.surfilter.gsxt.util;

import com.surfilter.gsxt.OprateException;
import com.surfilter.gsxt.crawler.PhantomJSDriverPools;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.interactions.Mouse;
import org.openqa.selenium.phantomjs.PhantomJSDriver;
import org.openqa.selenium.remote.UnreachableBrowserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class WebCrawlUtils {
	
	private static final Logger logger = LoggerFactory.getLogger(WebCrawlUtils.class);

	private PhantomJSDriver driver;
	
	private Long time_out = 20 * 60 * 1000l;
	
	public WebCrawlUtils() {
		super();
	}
	
	public WebCrawlUtils(PhantomJSDriver driver) {
		super();
		this.driver = driver;
	}

	public PhantomJSDriver getDriver() {
		return driver;
	}

	public void initDriverByPools() throws OprateException, InterruptedException{
		driver = PhantomJSDriverPools.getPhantomJSDriver(time_out);
	}

	public void initDriverDefault(){
		driver = HttpUtil.getPhantomJSDriver();
	}
	
	public void initDriver(Platform plat, String browserName, boolean javasriptenabled, String phantomjsPath, Map<String, Object> capabilitys, String[] phantomJsArgs, Integer dimensionW, Integer dimensionH){
		driver = HttpUtil.getPhantomJSDriver(plat, browserName, javasriptenabled, phantomjsPath, capabilitys, phantomJsArgs, dimensionW, dimensionH);
	}
	
	public String getCurrentUrl(){
		return driver.getCurrentUrl();
	}
	
	public void openWebPage(String url){
		while(true){
			try{
				driver.navigate().to(url);
				break;
			}catch(UnreachableBrowserException e){
				PhantomJSDriverPools.reopenPhantomJSDriver(driver);
				try {
					initDriverByPools();
				} catch (OprateException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}			
		}
	}

	public void inputStr(String str, String cssSelector){
		try{
			WebElement passwdInput = driver.findElementByCssSelector(cssSelector);
			passwdInput.sendKeys(str);
		}catch(Exception e){
			logger.error("输入信息：{}异常重试", cssSelector, e);
		}
	}


	public List<WebElement> findElementsByCssSelector(String selector){
		List<WebElement> eles = null;
		try{
			eles = driver.findElementsByCssSelector(selector);
		}catch(Exception e){
			logger.error("查找元素集：{}异常", selector, e);
		}
		return eles;
	}
	
	public List<WebElement> findElementsByXpath(String xpath){
		List<WebElement> eles = null;
		try{
			eles = driver.findElementsByXPath(xpath);
		}catch(Exception e){
			logger.error("查找元素集：{}异常", xpath, e);
		}
		return eles;
	}
	
	public List<WebElement> findElementsByTagName(String tagName){
		List<WebElement> eles = null;
		try{
			eles = driver.findElementsByTagName(tagName);
		}catch(Exception e){
			logger.error("查找元素集：{}异常", tagName, e);
		}
		return eles;
	}
	
	public List<WebElement> findElementsBy(By by){
		List<WebElement> eles = null;
		try{
			eles = driver.findElements(by);
		}catch(Exception e){
			logger.error("查找元素集：{}异常", by.toString(), e);
		}
		return eles;
	}
	
	public WebElement findElementBy(By by){
		WebElement result = null;
		try{
			result = driver.findElement(by);
		}catch(Exception e){
			logger.error("查找元素：{}异常", by.toString(), e);
		}
		return result;
	}
	
	public WebElement findElementByCssSelector(String selector){
		WebElement result = null;
		try{
			result = driver.findElementByCssSelector(selector);
		}catch(Exception e){
			logger.error("查找元素：{}异常", selector, e);
		}
		return result;
	}
	
	public WebElement findElementByCssSelector(WebElement ele, String selector){
		WebElement result = null;
		try{
			result = ele.findElement(By.cssSelector(selector));
		}catch(Exception e){
			logger.error("查找元素：{}异常", selector, e);
		}
		return result;
	}
	
	public WebElement findElementByXpath(String xpath){
		WebElement result = null;
		try{
			result = driver.findElementByXPath(xpath);
		}catch(Exception e){
			logger.error("查找元素：{}异常", xpath, e);
		}
		return result;
	}
	
	public void ajaxWait(long time){
		try {
			Thread.sleep(time);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void click(WebElement ele){
		ele.click();
	}
	
	public void sendKeys(WebElement ele, CharSequence keysToSend){
		ele.sendKeys(keysToSend);
	}
	
	public BufferedImage createElementImage(WebElement webElement)
			throws IOException {
		Point location = webElement.getLocation();
		Dimension size = webElement.getSize();
		BufferedImage originalImage = ImageIO.read(new ByteArrayInputStream(takeScreenshot()));
		BufferedImage croppedImage = originalImage.getSubimage(location.getX(),
				location.getY(), size.getWidth(), size.getHeight());
		return croppedImage;
	}
	
	public byte[] takeScreenshot() throws IOException {
		TakesScreenshot takesScreenshot = (TakesScreenshot) driver;
		return takesScreenshot.getScreenshotAs(OutputType.BYTES);
	}
	
	public boolean cutCurrentSitePicture(String dest_dir, String fileName, String format){
		boolean result = false;
		try{
			byte[] images = takeScreenshot();
			File destfile = new File(dest_dir);
			if(!destfile.exists())destfile.mkdirs();
			File rdestFile = new File(dest_dir + "/" + fileName + format);
			if(rdestFile.exists())rdestFile.delete();
			FileUtils.writeByteArrayToFile(rdestFile, images);
			if(rdestFile.exists())result = true;
		}catch(Exception e){
			logger.error("截取当前页面图片异常", e);
		}
		return result;
	}
	
	public void recoveryDriver(){
		try {
			clear();
			PhantomJSDriverPools.returnPhantomJSDriver(driver);
		} catch (OprateException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			logger.error("回收Driver异常", e);
		}
	}
	
	public void clear(){
		String clear_url = "http://127.0.0.1:80";
		openWebPage(clear_url);
	}
	
	public void close(){
		driver.close();
	}
	
	public void quit(){
		driver.quit();
	}

	public String getPageSource() {
		// TODO Auto-generated method stub
		return driver.getPageSource();
	}

	public Mouse getMouse() {
		return driver.getMouse();
	}

	public Set<String> getAllWindows() {
		return driver.getWindowHandles();
	}
	public String getNowWindow() {
		return driver.getWindowHandle();
	}

	public void switchToWindow(String window) {
		driver.switchTo().window(window);
	}

	//有问题
	public WebElement click(WebElement element, String selector) {
		WebElement el = element.findElement(By.cssSelector(selector));
		if ("a".equalsIgnoreCase(el.getTagName())) {
			JavascriptExecutor jse = new WebCrawlUtils().driver;
			jse.executeScript("arguments[0].setAttribute('target','_blank')", el);
		}
		el.click();
		return el;
	}
}
